home *** CD-ROM | disk | FTP | other *** search
/ PC User 2003 January / Disc 1 / PCU0103CD1.iso / entertn / demos / files / aomtrial.exe / AOM / AI / SCN33P4.XS < prev    next >
Encoding:
Text File  |  2002-08-16  |  23.6 KB  |  764 lines

  1. //==============================================================================
  2. // Scn33p4: AI Scenario Script for scenario 33 player 4
  3. //==============================================================================
  4. /*
  5.    AI owner:  Mike Kidd
  6.    Scenario owner: Jeff Brown
  7.  
  8.    Overview:
  9.    
  10.    Player 4 is Norse, and serves to basically play defense and prevent the 
  11.    HP from leaving his area in the first 30 minutes of gameplay.
  12.  
  13.    Player 4 will get upgrades, but doesn't train units.  His existing armies 
  14.    are allocated to four defend plans.  Three are near the borders between player
  15.    4 and the HP, the other is a general defense plan to protect the core of his
  16.    town.
  17.      
  18. */
  19. //==============================================================================
  20.  
  21.  
  22. include "scn lib.xs";
  23.  
  24.  
  25. // *****************************************************************************
  26. //
  27. // Globals
  28. //
  29. // *****************************************************************************
  30.  
  31.  
  32. // Cinematic blocks
  33.  
  34. const string cbDefendPoint = "2885";
  35. const string cbAttackGather = "2890";
  36. const string cbTownCenter = "2888";
  37. const string cbGarg = "2898";       // Gargarensis's hideout
  38. const string cbRouteA1 = "2891";      // East side
  39. const string cbRouteA2 = "2892";
  40. const string cbRouteA3 = "2893";
  41. const string cbRouteB1 = "2891";      // Center
  42. const string cbRouteB2 = "2892";
  43. const string cbRouteB3 = "2894";
  44. const string cbRouteC1 = "2891";      // West
  45. const string cbRouteC2 = "2895";
  46. const string cbRouteC3 = "2896";
  47. const string cbDefend1 = "2987";
  48. const string cbDefend2 = "2988";
  49. const string cbDefend3 = "2989";
  50.  
  51.  
  52. // Attack routes and queries
  53. int   routeA = -1;
  54. int   routeB = -1;
  55. int   routeC = -1;
  56.  
  57.  
  58. // Army control
  59. int   lastAttackPlan = -1;       // Used to find "my army" for god power position info
  60. int   defendPlan = -1;
  61. int   defend1 = -1;
  62. int   defend2 = -1;
  63. int   defend3 = -1;
  64. int   explorePlan = -1;
  65.  
  66. // The following are set in main() based on difficulty level.
  67. int      nextAttackTime = 180000;   // Will be adjusted for the wakeup time
  68. int      attackInterval = 240000;   // Attack every 4:00 
  69. float    attackSize = 3.0;
  70. float    attackMultiplier = 1.2;
  71. int      maxAttackSize = 8;
  72.  
  73. //    Upgrade timer control
  74. int      startTime = -1;
  75. int      endTime = -1;
  76.  
  77.  
  78. int   maintainQty1 = -1;         // Quantity to maintain
  79. int   maintainUnit1 = -1;        // Unit type
  80. int   maintainDelay1 = -1;       // Interval between training units
  81. vector   maintainGather1 = cInvalidVector;
  82. int   maintainID1 = -1;          // Maintain plan for primary military unit
  83.  
  84. int   maintainQty2 = -1;         // Quantity to maintain
  85. int   maintainUnit2 = -1;        // Unit type
  86. int   maintainDelay2 = -1;       // Interval between training units
  87. vector   maintainGather2 = cInvalidVector;
  88. int   maintainID2 = -1;          // Maintain plan for secondary military unit
  89.  
  90. int   maintainQty3 = -1;         // Quantity to maintain
  91. int   maintainUnit3 = -1;        // Unit type
  92. int   maintainDelay3 = -1;       // Interval between training units
  93. vector   maintainGather3 = cInvalidVector;
  94. int   maintainID3 = -1;          // Maintain plan for tertiary military unit
  95.  
  96. int   maintainQty4 = -1;         // Quantity to maintain
  97. int   maintainUnit4 = -1;        // Unit type
  98. int   maintainDelay4 = -1;       // Interval between training units
  99. vector   maintainGather4 = cInvalidVector;
  100. int   maintainID4 = -1;          // Maintain plan for quatenary military unit
  101.  
  102. int   maintainQtyScout = 1;
  103. int   maintainUnitScout = cUnitTypeScout;
  104. int   maintainDelayScout = 1;
  105. vector   maintainGatherScout = cInvalidVector;
  106. int   maintainIDScout = -1;      // Scout unit
  107.  
  108.  
  109.  
  110.  
  111.  
  112. // Misc.
  113. int   age2Time = -1;       // Will be adjusted in main() for difficulty
  114. int   age3Time = -1;        
  115. int   age4Time = -1;       
  116.  
  117. int   difficulty = -1;     // Global to store difficulty, set early in main.
  118.  
  119.  
  120.  
  121. // *****************************************************************************
  122. //
  123. //                                FUNCTIONS
  124. //
  125. // *****************************************************************************
  126.  
  127.  
  128. // Called by trigger when the cinematics are done
  129.  
  130. void wakeup(int parm=-1)
  131. {
  132.    static bool alreadyRun = false;
  133.    aiEcho("Wakeup running at "+timeString()+".");
  134.    if (alreadyRun == true)
  135.       return;
  136.    alreadyRun = true;
  137.  
  138.    startTime = xsGetTime();
  139.    endTime = startTime + 20*60*1000;   // When does the army arrive?
  140.  
  141.    if (age2Time > 0)
  142.       age2Time = age2Time + startTime; // Adjust for delay in wakeup.
  143.    if (age3Time > 0)
  144.       age3Time = age3Time + startTime;     
  145.    if (age4Time > 0)
  146.       age4Time = age4Time + startTime;
  147.    if (nextAttackTime  > 0)
  148.       nextAttackTime = nextAttackTime + startTime;
  149.  
  150.       // Init mid-priority defend plans to manage units at passes
  151.    defend1 =aiPlanCreate("Defend Plan 1", cPlanDefend);
  152.    if (defend1 >= 0)
  153.    {
  154.       aiPlanAddUnitType(defend1, cUnitTypeHuskarl, 0, 4, 4);    // Units around pass 1
  155.       aiPlanAddUnitType(defend1, cUnitTypeHeroNorse, 0, 4, 4);
  156.       aiPlanSetDesiredPriority(defend1, 30);                       // moderate, below scouting and attack but above general defense
  157.       aiPlanSetVariableVector(defend1, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbDefend1));
  158.       aiPlanSetVariableFloat(defend1, cDefendPlanEngageRange, 0, 30.0);
  159.       aiPlanSetVariableBool(defend1, cDefendPlanPatrol, 0, false);
  160.       aiPlanSetVariableFloat(defend1, cDefendPlanGatherDistance, 0, 15.0);
  161.       aiPlanSetVariableInt(defend1, cDefendPlanRefreshFrequency, 0, 5);
  162.       aiPlanSetNumberVariableValues(defend1, cDefendPlanAttackTypeID, 2, true);
  163.       aiPlanSetUnitStance(defend1, cUnitStanceDefensive);
  164.       aiPlanSetVariableInt(defend1, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  165.       aiPlanSetVariableInt(defend1, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  166.  
  167.       aiPlanSetInitialPosition(defend1, kbGetBlockPosition(cbAttackGather));
  168.       aiPlanSetActive(defend1); 
  169.       aiEcho("Creating defend1 plan.");
  170.    }
  171.  
  172.  
  173.    defend2 =aiPlanCreate("Defend Plan 2", cPlanDefend);
  174.    if (defend2 >= 0)
  175.    {
  176.       aiPlanAddUnitType(defend2, cUnitTypeThrowingAxeman, 0, 8, 8);    // Units around pass 2
  177.       aiPlanSetDesiredPriority(defend2, 30);                       // moderate, below scouting and attack but above general defense
  178.       aiPlanSetVariableVector(defend2, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbDefend2));
  179.       aiPlanSetVariableFloat(defend2, cDefendPlanEngageRange, 0, 30.0);
  180.       aiPlanSetVariableBool(defend2, cDefendPlanPatrol, 0, false);
  181.       aiPlanSetVariableFloat(defend2, cDefendPlanGatherDistance, 0, 15.0);
  182.       aiPlanSetVariableInt(defend2, cDefendPlanRefreshFrequency, 0, 5);
  183.       aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  184.       aiPlanSetUnitStance(defend2, cUnitStanceDefensive);
  185.       aiPlanSetVariableInt(defend2, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  186.       aiPlanSetVariableInt(defend2, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  187.  
  188.       aiPlanSetInitialPosition(defend2, kbGetBlockPosition(cbAttackGather));
  189.       aiPlanSetActive(defend2); 
  190.       aiEcho("Creating defend2 plan.");
  191.    }
  192.  
  193.  
  194.    defend3 =aiPlanCreate("Defend Plan 3", cPlanDefend);
  195.    if (defend3 >= 0)
  196.    {
  197.       aiPlanAddUnitType(defend3, cUnitTypeJarl, 0, 8, 8);    // Units around pass 3
  198.       aiPlanSetDesiredPriority(defend3, 30);                       // moderate, below scouting and attack but above general defense
  199.       aiPlanSetVariableVector(defend3, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbDefend3));
  200.       aiPlanSetVariableFloat(defend3, cDefendPlanEngageRange, 0, 30.0);
  201.       aiPlanSetVariableBool(defend3, cDefendPlanPatrol, 0, false);
  202.       aiPlanSetVariableFloat(defend3, cDefendPlanGatherDistance, 0, 15.0);
  203.       aiPlanSetVariableInt(defend3, cDefendPlanRefreshFrequency, 0, 5);
  204.       aiPlanSetNumberVariableValues(defend3, cDefendPlanAttackTypeID, 2, true);
  205.       aiPlanSetUnitStance(defend3, cUnitStanceDefensive);
  206.       aiPlanSetVariableInt(defend3, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  207.       aiPlanSetVariableInt(defend3, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  208.  
  209.       aiPlanSetInitialPosition(defend3, kbGetBlockPosition(cbAttackGather));
  210.       aiPlanSetActive(defend3); 
  211.       aiEcho("Creating defend3 plan.");
  212.    }
  213.  
  214.  
  215.    // Init low-priority defend plan to manage all extra mil units
  216.    defendPlan =aiPlanCreate("Defend Plan", cPlanDefend);
  217.    if (defendPlan >= 0)
  218.    {
  219.       aiPlanAddUnitType(defendPlan, cUnitTypeHumanSoldier, 0, 200, 200);    // All unassigned mil units except giants
  220.       aiPlanAddUnitType(defendPlan, cUnitTypeBallista, 0, 200, 200);
  221.       aiPlanSetDesiredPriority(defendPlan, 10);                       // Way low, below scouting and attack
  222.       aiPlanSetVariableVector(defendPlan, cDefendPlanDefendPoint, 0, kbGetBlockPosition(cbDefendPoint));
  223.       aiPlanSetVariableFloat(defendPlan, cDefendPlanEngageRange, 0, 50.0);
  224.       aiPlanSetVariableBool(defendPlan, cDefendPlanPatrol, 0, false);
  225.       aiPlanSetVariableFloat(defendPlan, cDefendPlanGatherDistance, 0, 20.0);
  226.       aiPlanSetVariableInt(defendPlan, cDefendPlanRefreshFrequency, 0, 5);
  227.       aiPlanSetNumberVariableValues(defendPlan, cDefendPlanAttackTypeID, 2, true);
  228.       aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit);
  229.       aiPlanSetVariableInt(defendPlan, cDefendPlanAttackTypeID, 1, cUnitTypeBuilding);
  230.       aiPlanSetUnitStance(defendPlan, cUnitStanceDefensive);
  231.       aiPlanSetInitialPosition(defendPlan, kbGetBlockPosition(cbAttackGather));
  232.       aiPlanSetActive(defendPlan); 
  233.       aiEcho("Creating defend plan");
  234.    }
  235.  
  236.    xsEnableRule("scout");
  237.    xsEnableRule("attackGenerator");
  238.    xsEnableRule("upgradeGenerator");
  239. }
  240.  
  241.  
  242.  
  243.  
  244.  
  245. void attack(int size=0)
  246. {
  247.    int   attackID=aiPlanCreate("Attack at "+timeString(true)+" ", cPlanAttack);
  248.    if (attackID < 0) 
  249.       return;
  250.  
  251.    if (aiPlanSetVariableInt(attackID, cAttackPlanPlayerID, 0, 1) == false)
  252.       return;
  253.  
  254.    if (aiPlanSetNumberVariableValues(attackID, cAttackPlanTargetTypeID, 3, true) == false)
  255.       return;
  256.  
  257.    aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit);
  258.    aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding);
  259.    aiPlanSetVariableInt(attackID, cAttackPlanTargetTypeID, 2, cUnitTypeAbstractWall);
  260.  
  261.  
  262.    
  263.    switch(aiRandInt(3))
  264.    {
  265.    case 0:
  266.       {
  267.          aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeA);
  268.          break;
  269.       }
  270.    case 1:
  271.       {
  272.          aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeB);
  273.          break;
  274.       }
  275.    case 2:
  276.       {
  277.          aiPlanSetVariableInt(attackID, cAttackPlanAttackRouteID, 0, routeC);
  278.          break;
  279.       }
  280.    }
  281.  
  282.  
  283.    aiPlanSetVariableVector(attackID, cAttackPlanGatherPoint, 0, kbGetBlockPosition(cbAttackGather));
  284.    aiPlanSetVariableFloat(attackID, cAttackPlanGatherDistance, 0, 20.0);
  285.  
  286.  
  287.    aiPlanAddUnitType(attackID, maintainUnit1, 0, (size+8)/10, (size+8)/10);  // cyclops
  288.    aiPlanAddUnitType(attackID, maintainUnit2, 0, (4*size+2)/10, (4*size+2)/10);  // hippikon
  289.    aiPlanAddUnitType(attackID, maintainUnit3, 0, (5*size+5)/10, (5*size+5)/10);  // toxotes
  290.  
  291.    if ( (endTime - xsGetTime()) < 10*60*1000)
  292.    {
  293.       aiEcho("  adding hydra(s) to attack plan.");
  294.       aiPlanAddUnitType(attackID, maintainUnit4, 0, (size+3)/5, (size+3)/5);      // hydra
  295.    }
  296.  
  297.    aiPlanSetInitialPosition(attackID, kbGetBlockPosition(cbAttackGather));
  298.    aiPlanSetRequiresAllNeedUnits(attackID, false);
  299.    aiPlanSetDesiredPriority(attackID, 50);   // Less than scouting, more than defense
  300.    aiPlanSetActive(attackID);
  301.    aiEcho("Activating attack plan "+attackID+" with appx "+size+" units.");
  302.    lastAttackPlan = attackID; // update the global var
  303. }
  304.  
  305.  
  306.  
  307.  
  308. void main()
  309. {
  310.    aiEcho("Starting Scn33p4.xs");
  311.  
  312.    //Calculate some areas.
  313.    kbAreaCalculate(1200.0);
  314.    aiRandSetSeed();
  315.    kbSetTownLocation(kbGetBlockPosition(cbTownCenter));
  316.  
  317. /*
  318.    aiSetAgeEventHandler(cAge2, "age2EventHandler");
  319.    aiSetAgeEventHandler(cAge3, "age3EventHandler");
  320.    aiSetAgeEventHandler(cAge4, "age4EventHandler");
  321. */
  322.    aiSetAttackResponseDistance(10.0);
  323.  
  324.    // Kill escrows
  325.    kbEscrowSetPercentage( cEconomyEscrowID, cAllResources, 0.0);
  326.    kbEscrowSetPercentage( cMilitaryEscrowID, cAllResources, 0.0);
  327.    kbEscrowAllocateCurrentResources();
  328.  
  329.  
  330.    int   armyReserveSize = -1;   // Target size for total reserve army, to be adjusted for difficulty
  331.    int   standardDelay = -1;     // Used to set unit-training delay times, adjusted for difficulty
  332.  
  333.    // Set difficulty vars
  334.    difficulty = aiGetWorldDifficulty();
  335.    aiEcho("Difficulty = "+difficulty);   
  336.  
  337.    switch(difficulty)      // Set up the attack control and age-up parameters
  338.    {
  339.    case 0:     // Easy
  340.       {
  341.          nextAttackTime = 1000;     // 1 sec
  342.          attackInterval = 240000;   // 4 min
  343.          attackSize = 3;          
  344.          attackMultiplier = 1.3;    // 30% per interval
  345.          maxAttackSize = 8;
  346.          age2Time = -1;       // N/A
  347.          age3Time = 1200000;  // 20 min
  348.          age4Time = 40*60*1000;       
  349.          armyReserveSize = 12;
  350.          standardDelay = 1;  // seconds
  351.          break;
  352.       }
  353.    case 1:     // Moderate
  354.       {
  355.          nextAttackTime = 1000;   // 1 sec 
  356.          attackInterval = 180000;   // 3 min
  357.          attackSize = 4.0;          
  358.          attackMultiplier = 1.3;    // 20% per period
  359.          maxAttackSize = 11;
  360.          age2Time = -1;       // N/A
  361.          age3Time = 720000;   // 12 min
  362.          age4Time = 20*60*1000;      
  363.          armyReserveSize = 16;
  364.          standardDelay = 1;  // seconds
  365.          break;
  366.       }
  367.    case 2:     // Difficult
  368.       {
  369.          nextAttackTime = 1000;     
  370.          attackInterval = 120000;
  371.          attackSize = 6.0;
  372.          attackMultiplier = 1.3;    // 30% per period
  373.          maxAttackSize = 15;
  374.          age2Time = -1;       // N/A
  375.          age3Time = 4*60*1000;   // 4 min
  376.          age4Time = 12*60*1000;       
  377.          armyReserveSize = 25;
  378.          standardDelay = 1;  // seconds
  379.          break;
  380.       }
  381.    case 3:     // Nightmare
  382.       {
  383.          nextAttackTime = 1000;
  384.          attackInterval = 120000;
  385.          attackSize = 8.0;
  386.          attackMultiplier = 1.4;    // 40% per period
  387.          maxAttackSize = 25;
  388.          age2Time = -1;       // N/A
  389.          age3Time = 1*60*1000;   // 1 min
  390.          age4Time = 8*60*1000;       
  391.          armyReserveSize = 40;
  392.          standardDelay = 1;  // seconds
  393.          break;
  394.       }
  395.    }
  396.  
  397.  
  398.  
  399.    // Set global unit control vars
  400.    maintainQty1 = (armyReserveSize+8)/10;         // Quantity to maintain
  401.    maintainUnit1 = cUnitTypeCyclops;        // Unit type
  402.    maintainDelay1 = standardDelay;       // Interval between training units
  403.    maintainGather1 = cInvalidVector;
  404.  
  405.    maintainQty2 = (4*armyReserveSize+2)/10;         // Quantity to maintain
  406.    maintainUnit2 = cUnitTypeHippikon;        // Unit type
  407.    maintainDelay2 = standardDelay;       // Interval between training units
  408.    maintainGather2 = cInvalidVector;
  409.  
  410.    maintainQty3 = (4*armyReserveSize+6)/10;         // Quantity to maintain
  411.    maintainUnit3 = cUnitTypeToxotes;        // Unit type
  412.    maintainDelay3 = standardDelay;       // Interval between training units
  413.    maintainGather3 = cInvalidVector;
  414.  
  415.    maintainQty4 = (armyReserveSize+5)/10;         // Quantity to maintain
  416.    maintainUnit4 = cUnitTypeHydra;        // Unit type
  417.    maintainDelay4 = standardDelay;       // Interval between training units
  418.    maintainGather4 = cInvalidVector;
  419.  
  420.  
  421.    maintainQtyScout = 1;
  422.    maintainUnitScout = cUnitTypeRaven;
  423.    maintainDelayScout = 1;
  424.    maintainGatherScout = cInvalidVector;
  425.  
  426.  
  427.    // Init attack routes
  428.    routeA = attackRoute("Attack Route A", cbRouteA1, cbRouteA2, cbRouteA3);
  429.    routeB = attackRoute("Attack Route B", cbRouteB1, cbRouteB2, cbRouteB3);
  430.    routeC = attackRoute("Attack Route C", cbRouteC1, cbRouteC2, cbRouteC3);
  431. /*
  432.    // Init maintain plans
  433.    if (maintainUnit1 > 0)
  434.       maintainID1 = maintainUnit(maintainUnit1, maintainQty1, maintainGather1, maintainDelay1);
  435.    if (maintainUnit2 > 0)
  436.       maintainID2 = maintainUnit(maintainUnit2, maintainQty2, maintainGather2, maintainDelay2); 
  437.    if (maintainUnit3 > 0)
  438.       maintainID3 = maintainUnit(maintainUnit3, maintainQty3, maintainGather3, maintainDelay3);  
  439.    if (maintainUnit4 > 0)
  440.       maintainID4 = maintainUnit(maintainUnit4, maintainQty4, maintainGather4, maintainDelay4);  
  441.    if (maintainUnitScout > 0)
  442.       maintainIDScout = maintainUnit(maintainUnitScout, maintainQtyScout, maintainGatherScout, maintainDelayScout);
  443.  
  444. */
  445.  
  446.  
  447. /*
  448.    // Initialize the target queries
  449.    queryP1Units = kbUnitQueryCreate("Player 1 Units");
  450.    configQuery(queryP1Units, cUnitTypeUnit, -1, cUnitStateAlive, 1);
  451. */
  452.  
  453.    wakeup(0); // Wake up immediately, don't wait for aiFunc trigger.
  454.  
  455. }
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463. // *****************************************************************************
  464. //
  465. // RULES
  466. //
  467. // *****************************************************************************
  468. /*rule cheatScout   // Spawn a fenris wolf if none exist
  469.    active
  470.    minInterval 15
  471. {
  472.    int count = -1;
  473.    count = kbUnitCount(2, maintainUnitScout, cUnitStateAlive);
  474.    if (count < maintainQtyScout)
  475.       aiUnitCreateCheat( 2, maintainUnitScout, kbGetBlockPosition(cbAttackGather), "Scout group", maintainQtyScout - count); 
  476.  
  477. }*/
  478.  
  479.  
  480.  
  481. rule favorGenerator
  482.    active
  483.    minInterval 15
  484. {
  485.    aiResourceCheat( 2, cResourceFavor, 100.0 );    // Max out the favor every 15 seconds
  486.    kbEscrowAllocateCurrentResources();             // Make sure the escrow knows about it.
  487. }
  488.  
  489.  
  490. rule scout
  491.    inactive
  492.    minInterval 5
  493. {
  494.    // just set up an explore plan
  495.    int explorePlan = aiPlanCreate("Explore", cPlanExplore);
  496.    if(explorePlan >= 0)
  497.    {
  498.       aiPlanSetVariableFloat( explorePlan, cExplorePlanLOSMultiplier,  0, 4.0 );
  499.       aiPlanAddUnitType(explorePlan, maintainUnitScout, 1, 1, 1);
  500.       aiPlanSetDesiredPriority(explorePlan, 90);
  501.       aiPlanSetInitialPosition(explorePlan, kbGetBlockPosition(cbAttackGather));
  502.       aiPlanSetActive(explorePlan);
  503.    }
  504.  
  505.    int explore2 = aiPlanCreate("Explore 2", cPlanExplore);
  506.    if(explore2 >= 0)
  507.    {
  508.       aiPlanSetVariableFloat( explore2, cExplorePlanLOSMultiplier,  0, 4.0 );
  509.       aiPlanAddUnitType(explore2, maintainUnitScout, 1, 1, 1);
  510.       aiPlanSetDesiredPriority(explore2, 90);
  511.       aiPlanSetInitialPosition(explore2, kbGetBlockPosition(cbAttackGather));
  512.       aiPlanSetActive(explore2);
  513.    }
  514.  
  515.    xsDisableSelf();
  516. }
  517.  
  518.  
  519.  
  520. /*
  521. rule goToAge2
  522.    inactive
  523.    minInterval 10
  524. {
  525.    if ( xsGetTime() < age2Time)
  526.       return;
  527.    researchTech(cTechAge2Heimdall);
  528.    xsDisableSelf();
  529. }
  530.  
  531.  
  532.  
  533. rule goToAge3
  534.    inactive
  535.    mininterval 20
  536. {
  537.    if ( xsGetTime() < age3Time )
  538.       return;
  539.    researchTech(cTechAge3Njord);
  540.    xsDisableSelf();
  541. }
  542.  
  543.  
  544. rule goToAge4
  545.    inactive
  546.    mininterval 20
  547. {
  548.    if ( xsGetTime() < age4Time )
  549.       return;
  550.    researchTech(cTechAge4Hel);
  551.    xsDisableSelf();
  552. }
  553. */
  554.  
  555.  
  556.  
  557. rule getAge2UnitUpgrades
  558.    inactive
  559.    minInterval 20
  560. {
  561. //   researchTech(cTechMediumInfantry);
  562. //   researchTech(cTechMediumCavalry);
  563.    xsDisableSelf();
  564. }
  565.  
  566. rule getAge2ArmoryUpgrades
  567.    inactive
  568.    minInterval 20
  569. {
  570.  
  571.    aiEcho("Getting age 2 armory upgrades");
  572.    researchTech(cTechCopperWeapons);
  573.    researchTech(cTechCopperMail);
  574.    researchTech(cTechCopperShields);
  575.    xsDisableSelf();
  576. }
  577.  
  578. rule getAge3UnitUpgrades
  579.    inactive
  580.    minInterval 20
  581. {
  582.  
  583. //   researchTech(cTechHeavyInfantry);
  584.  //  researchTech(cTechHeavyCavalry);
  585.    xsDisableSelf();
  586. }
  587.  
  588. rule getAge3ArmoryUpgrades
  589.    inactive
  590.    minInterval 20
  591. {
  592.    aiEcho("Getting age 3 armory upgrades");
  593.    researchTech(cTechBronzeWeapons);
  594.    researchTech(cTechBronzeMail);
  595.    researchTech(cTechBronzeShields);
  596.    xsDisableSelf();
  597. }
  598.  
  599. rule getAge4UnitUpgrades
  600.    inactive
  601.    minInterval 20
  602. {
  603.  
  604. //   researchTech(cTechChampionInfantry);
  605. //   researchTech(cTechChampionCavalry);
  606.    xsDisableSelf();
  607. }
  608.  
  609. rule getAge4ArmoryUpgrades
  610.    inactive
  611.    minInterval 20
  612. {
  613.    aiEcho("Getting age 4 armory upgrades");
  614.    researchTech(cTechIronWeapons);
  615.    researchTech(cTechIronMail);
  616.    researchTech(cTechIronShields);
  617.    xsDisableSelf();
  618. }
  619.  
  620.  
  621. rule upgradeGenerator
  622.    minInterval 10
  623.    inactive
  624. {
  625.    // Progressively get unit upgrades throughout
  626.    // Take the time from startTime to endTime, divide into six segments.
  627.    // At the end of each segment, get a set of unit or armory upgrades.
  628.  
  629.  
  630.  
  631.    static int interval = 0;
  632.    static int nextTime = 0;
  633.    static int count = 0;
  634.  
  635.    if (interval == 0) 
  636.    {
  637.       interval = (endTime - startTime)/6;
  638.       nextTime = startTime + interval;
  639.    }
  640.  
  641.    if (nextTime > xsGetTime())
  642.       return;     // It is not yet our time.
  643.  
  644.    // It is time, do something
  645.    switch( count )      // Activate the appropriate upgrade rule, reset nextTime timer.
  646.    {
  647.    case 0:
  648.       {
  649.          xsEnableRule("getAge2UnitUpgrades");
  650.          count = count + 1;
  651.          nextTime = nextTime + interval;
  652.          break;
  653.       }
  654.    case 1:
  655.       {
  656.          xsEnableRule("getAge2ArmoryUpgrades");
  657.          count = count + 1;
  658.          nextTime = nextTime + interval;
  659.          break;
  660.       }
  661.    case 2:
  662.       {
  663.          xsEnableRule("getAge3UnitUpgrades");
  664.          count = count + 1;
  665.          nextTime = nextTime + interval;
  666.          break;
  667.       }
  668.    case 3:
  669.       {
  670.          xsEnableRule("getAge3ArmoryUpgrades");
  671.          count = count + 1;
  672.          nextTime = nextTime + interval;
  673.          break;
  674.       }
  675.    case 4:
  676.       {
  677.          xsEnableRule("getAge4UnitUpgrades");
  678.          count = count + 1;
  679.          nextTime = nextTime + interval;
  680.          break;
  681.       }
  682.    case 5:
  683.       {
  684.          xsEnableRule("getAge4ArmoryUpgrades");
  685.          count = count + 1;
  686.          xsDisableSelf();
  687.          break;
  688.       }
  689.    }
  690.  
  691.  
  692. }
  693.  
  694. rule attackGenerator
  695.    minInterval 10
  696.    inactive
  697. {
  698. xsDisableSelf();
  699. return;
  700.  
  701.    //aiEcho("attack check running, next time is "+nextAttackTime);
  702.    if ( xsGetTime() < nextAttackTime )
  703.       return;
  704.  
  705.    attack(attackSize);
  706.    nextAttackTime = xsGetTime() + attackInterval;
  707.    attackSize = attackSize * attackMultiplier;
  708.    if (attackSize > maxAttackSize)
  709.       attackSize = maxAttackSize;
  710.    aiEcho("Next attack size will be "+attackSize+".");
  711. }
  712.  
  713.  
  714.  
  715.  
  716.  
  717. /*
  718. rule useUndermine // Look for 2 walls near my army
  719.    minInterval 5
  720.    inactive
  721. {
  722.    int targetUnit = -1;
  723.    int attackArmyID = -1;
  724.  
  725.    if (lastAttackPlan < 0)
  726.       return;
  727.    vector pVec = aiPlanGetLocation(lastAttackPlan);
  728.    if (xsVectorGetX(pVec)<0)
  729.       return;
  730.  
  731.    static int tempQuery = -1;
  732.    if (tempQuery < 0)
  733.    {  // Doesn't exist, set it up
  734.       tempQuery = kbUnitQueryCreate("useUndermine");
  735.  
  736.       if ( configQuery(tempQuery, cUnitTypeAbstractWall, -1, cUnitStateAliveOrBuilding, 1, pVec, true, 25) == false)
  737.          return;
  738.    }
  739.    else
  740.       kbUnitQuerySetPosition(tempQuery, pVec); // Because pVec changes as army moves
  741.  
  742.    kbUnitQueryResetResults(tempQuery);
  743.    int targetCount = kbUnitQueryExecute(tempQuery);  
  744.  
  745.    if (targetCount < 2)
  746.       return;
  747.    targetUnit = kbUnitQueryGetResult(tempQuery, 0);  // grab first wall
  748.  
  749.    // confirm LOS
  750.    if ( kbUnitVisible(targetUnit) != true )
  751.    {
  752.       aiEcho("Undermine: Don't have LOS for unit "+targetUnit+" "+kbGetProtoUnitName(targetUnit));
  753.       return;
  754.    }
  755.  
  756.    aiEcho("Using Undermine at "+kbUnitGetPosition(targetUnit));
  757.    if ( aiCastGodPowerAtPosition(cTechUndermine, kbUnitGetPosition(targetUnit)) == true)
  758.       xsDisableSelf();
  759.    else 
  760.       aiEcho("Undermine failed at "+kbUnitGetPosition(targetUnit));
  761. }
  762. */
  763.  
  764.